include("shared.lua")

local texGradientDown = surface.GetTextureID("gui/gradient_down")
local wid, hei = 650, 256
function ENT:DrawDashboard(pos, ang, scale)
	cam.Start3D2D(pos, ang, scale)
		local speed = self:GetVelocity():Length()
		local intensity = math.min(255, speed * 0.05 * RSCALE)
		surface.SetDrawColor(0, 0, 0, 160)
		surface.DrawRect(16, 8, 48, 128)
		surface.SetDrawColor(intensity, 30, 255 - intensity, 160)
		local barhei = math.max(4, intensity * 0.502)
		surface.DrawRect(16, 8 + (128 - barhei), 48, barhei)
		surface.SetDrawColor(255, 255, 255, 160)
		surface.DrawOutlinedRect(16, 8, 48, 128)

		surface.SetDrawColor(0, 0, 0, 160)
		surface.DrawRect(148, 8, 200, 48)
		surface.SetTexture(texGradientDown)
		surface.SetDrawColor(20, 255, 20, 160)
		local health = self:GetVehicleHealth()
		surface.DrawTexturedRect(148, 8, 2 * (health/250)*100, 48)
		surface.SetDrawColor(20, 255, 20, 16)
		surface.DrawRect(148, 8, 2 * (health/250)*100, 48)
		surface.SetDrawColor(255, 255, 255, 160)
		surface.DrawOutlinedRect(148, 8, 200, 48)
		draw.SimpleText(math.floor((health/250)*100).."%", "ScoreboardSub", 248, 32, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)

		if health == 0 then
			draw.DrawText("ENGINE OFFLINE", "ScoreboardSub", 248, 64, Color(255, 0, 0, math.max(0, math.sin(RealTime() * 7) * 255)), TEXT_ALIGN_CENTER)
		else
			draw.DrawText("Engine: "..math.floor((health/250)*100).."%", "ScoreboardSub", 248, 64, color_white, TEXT_ALIGN_CENTER)
		end

		self:CallOnAll("DrawDashboard", pos, ang, scale)

		draw.DrawText(math.floor(0.056818181 * speed * RSCALE).." MPH", "ScoreboardSub", 72, 8, color_white, TEXT_ALIGN_LEFT)
	cam.End3D2D()
end

function ENT:DrawBackBumper(pos, ang, scale)
	cam.Start3D2D(pos, ang, scale)
		surface.SetDrawColor(0, 0, 0, 160)
		surface.DrawRect(-150, 0, 300, 64)
		surface.SetDrawColor(20, 255, 20, 160)
		local health = self:GetVehicleHealth()
		surface.DrawRect(-150, 0, 3 * (health/250)*100, 64)
		surface.SetDrawColor(255, 255, 255, 160)
		surface.DrawOutlinedRect(-150, 0, 300, 64)

		if health == 0 and 0 < math.sin(RealTime() * 7) then
			draw.SimpleText("ENGINE OFFLINE", "ScoreboardSub", 0, 32, COLOR_RED, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
		end
	cam.End3D2D()
end

local colFrontLight = Color(30, 30, 255, 255)
local colBackLight = Color(255, 30, 30, 255)
local colLight = Color(255, 255, 255, 255)
local matLight = Material("sprites/light_ignorez")
function ENT:DrawHeadlight(pos, normal, col)
	local ViewNormal = pos - EyePos()
	local Distance = ViewNormal:Length() * SCALE
	ViewNormal:Normalize()
	local ViewDot = ViewNormal:Dot(normal) * -1

	if ViewDot >= 0 then
		local Visibile = util.PixelVisible(pos, 16 * SCALE, self.PixVis)
		if not Visibile then return end

		render.SetMaterial(matLight)
		local Size = math.Clamp(Distance * Visibile * 2 * ViewDot, 92 * SCALE, 400 * SCALE)
		Distance = math.Clamp(Distance, 32 * SCALE, 800 * SCALE)
		col.a = math.Clamp((1000 * SCALE - Distance) * Visibile * 1.5 * ViewDot, 0, 180)
		render.DrawSprite(pos, Size, Size, col, Visibile * ViewDot)
		colLight.a = col.a
		render.DrawSprite(pos, Size * 0.5, Size * 0.5, colLight, Visibile * ViewDot)
	end
end

local colTrail = Color(0, 30, 0, 255)
local matBeam = Material("Effects/laser1")
local matGlow = Material("sprites/glow04_noz")
function ENT:Draw()
	self:DrawModel()
	self:SetModelScale(SCALE, 0)

	local vPos = self:GetPos()
	if EyePos():Distance(vPos) < 2048 * SCALE then
		--self:DrawDashboard(self:GetDashboardPos(), self:GetDashboardAng(), 0.05 * SCALE)
		self:DrawBackBumper(self:GetBackBumperPos(), self:GetBackBumperAng(), 0.1 * SCALE)
	end

	if self:GetVehicleHealth() == 0 then return end

	local speed = self:GetVelocity():Length() * RSCALE
	local intensity = math.min(255, speed * 0.05)

	local right = self:GetRight()
	local fwd = self:GetForward()
	local backleft = vPos + fwd * self.Back + right * self.LeftLight
	local backright = vPos + fwd * self.Back + right * self.RightLight

	self:DrawHeadlight(vPos + fwd * self.Front + right * self.LeftLight, fwd, colFrontLight)
	self:DrawHeadlight(vPos + fwd * self.Front + right * self.RightLight, fwd, colFrontLight)
	self:DrawHeadlight(backleft, fwd * -1, colBackLight)
	self:DrawHeadlight(backright, fwd * -1, colBackLight)

	render.SetMaterial(matBeam)
	render.StartBeam(#self.RightTrails + 1)
		colTrail.r = intensity
		colTrail.b = 255 - intensity
		render.AddBeam(backright, 128 * SCALE, 0, colTrail)
		for i=1, #self.RightTrails do
			local r = math.min(255, self.TrailSpeeds[i])
			colTrail.r = r
			colTrail.b = 255 - r
			render.AddBeam(self.RightTrails[i], SCALE * (128 - i * 3), i, colTrail)
		end
	render.EndBeam()

	render.StartBeam(#self.LeftTrails + 1)
		colTrail.r = intensity
		colTrail.b = 255 - intensity
		render.AddBeam(backleft, 128 * SCALE, 0, colTrail)
		for i=1, #self.LeftTrails do
			local r = math.min(255, self.TrailSpeeds[i])
			colTrail.r = r
			colTrail.b = 255 - r
			render.AddBeam(self.LeftTrails[i], SCALE * (128 - i * 3), i, colTrail)
		end
	render.EndBeam()

	local particle = self.Emitter:Add("effects/select_ring", backright)
	particle:SetColor(intensity, 30, 255 - intensity)
	particle:SetDieTime(math.Rand(0.75, 1))
	particle:SetStartAlpha(200)
	particle:SetEndAlpha(0)
	particle:SetStartSize(16 * SCALE)
	particle:SetEndSize(2 * SCALE)

	local particle2 = self.Emitter:Add("effects/select_ring", backleft)
	particle2:SetColor(intensity, 30, 255 - intensity)
	particle2:SetDieTime(math.Rand(0.75, 1))
	particle2:SetStartAlpha(200)
	particle2:SetEndAlpha(0)
	particle2:SetStartSize(16 * SCALE)
	particle2:SetEndSize(2 * SCALE)

	if 6000 < speed then
		local delta = speed - 6000
		local smokeparticle = self.Emitter:Add("noxctf/sprite_flame", vPos + self:OBBMaxs().x * 2 * fwd)
		smokeparticle:SetColor(255, 255, 255)
		smokeparticle:SetDieTime(math.Rand(0.4, 0.65))
		smokeparticle:SetStartAlpha(math.min(128, delta * 0.07))
		smokeparticle:SetEndAlpha(0)
		smokeparticle:SetStartSize(math.min(70, delta * 0.055) * SCALE)
		smokeparticle:SetEndSize(0)
		smokeparticle:SetRollDelta(math.Rand(-100, 100))
		smokeparticle:SetRoll(math.Rand(0, 360))
	end

	if 4000 < speed and 6000 < math.random(4000, speed) then
		local smokeparticle = self.Emitter:Add("noxctf/sprite_flame", vPos + fwd * self.Front + right * self.Left)
		smokeparticle:SetDieTime(math.Rand(0.8, 1.4))
		smokeparticle:SetStartAlpha(230)
		smokeparticle:SetEndAlpha(180)
		smokeparticle:SetStartSize(math.Rand(12, 16) * SCALE)
		smokeparticle:SetEndSize(0)
		smokeparticle:SetRollDelta(math.Rand(-30, 30))
		smokeparticle:SetRoll(math.Rand(0, 360))

		local smokeparticle2 = self.Emitter:Add("noxctf/sprite_flame", vPos + fwd * self.Front + right * self.Right)
		smokeparticle2:SetDieTime(math.Rand(0.8, 1.4))
		smokeparticle2:SetStartAlpha(230)
		smokeparticle2:SetEndAlpha(180)
		smokeparticle2:SetStartSize(math.Rand(12, 16) * SCALE)
		smokeparticle2:SetEndSize(0)
		smokeparticle2:SetRollDelta(math.Rand(-30, 30))
		smokeparticle2:SetRoll(math.Rand(0, 360))
	elseif 2500 < speed and 4000 < math.random(2500, speed) then
		local smokeparticle = self.Emitter:Add("sprites/glow04_noz", vPos + fwd * self.Front + right * self.Left)
		--smokeparticle:SetColor(255, 100, 255)
		smokeparticle:SetDieTime(math.Rand(0.75, 1.5))
		smokeparticle:SetStartAlpha(255)
		smokeparticle:SetEndAlpha(0)
		smokeparticle:SetStartSize(math.Rand(4, 8) * SCALE)
		smokeparticle:SetEndSize(math.Rand(1, 2) * SCALE)
		smokeparticle:SetRollDelta(math.Rand(-60, 60))
		smokeparticle:SetRoll(math.Rand(0, 360))

		local smokeparticle2 = self.Emitter:Add("sprites/glow04_noz", vPos + fwd * self.Front + right * self.Right)
		--smokeparticle2:SetColor(255, 100, 255)
		smokeparticle2:SetDieTime(math.Rand(0.75, 1.5))
		smokeparticle2:SetStartAlpha(255)
		smokeparticle2:SetEndAlpha(0)
		smokeparticle2:SetStartSize(math.Rand(4, 8) * SCALE)
		smokeparticle2:SetEndSize(math.Rand(1, 2) * SCALE)
		smokeparticle2:SetRollDelta(math.Rand(-60, 60))
		smokeparticle2:SetRoll(math.Rand(0, 360))
	end
end

function ENT:Initialize()
	--self.Engine1Sound = CreateSound(self, "ambient/machines/thumper_amb.wav")
	self.Engine1Sound = CreateSound(self, "ambient/machines/laundry_machine1_amb.wav")
	self.Engine2Sound = CreateSound(self, "ambient/machines/train_idle.wav")
	self.Engine3Sound = CreateSound(self, "ambient/machines/electric_machine.wav")
	--self.Engine3Sound = CreateSound(self, "ambient/fire/fire_big_loop1.wav")
	self.AlarmSound = CreateSound(self, "ambient/alarms/combine_bank_alarm_loop4.wav")

	self.Emitter = ParticleEmitter(self:GetPos())
	self.Emitter:SetNearClip(16, 22)

	self.NextTrail = 0

	self.Maxs = self:OBBMaxs()
	self.Mins = self:OBBMins()
	self.Bottom = self.Mins.z
	self.Top = self.Maxs.z
	self.Front = self.Maxs.x
	self.Back = self.Mins.x
	self.Left = self.Mins.y
	self.LeftLight = self.Mins.y + 7 * SCALE
	self.Right = self.Maxs.y
	self.RightLight = self.Maxs.y - 7 * SCALE

	self.PixVis = util.GetPixelVisibleHandle()

	self.RightTrails = {}
	self.LeftTrails = {}
	self.TrailSpeeds = {}
end

function ENT:Think()
	if self:GetVehicleHealth() <= 0 then
		if self.Engine1Sound:IsPlaying() then
			self.Engine1Sound:Stop()
			self.Engine2Sound:Stop()
			self.Engine3Sound:Stop()
			self:EmitSound("ambient/machines/thumper_shutdown1.wav")
		end
		self.AlarmSound:PlayEx(0.9, 200 + math.sin(RealTime() * 20) * 30)
	else
		if self.AlarmSound:IsPlaying() then
			self.AlarmSound:Stop()
			self:EmitSound("ambient/machines/thumper_startup1.wav")
		end

		local pitch1 = self:GetVelocity():Length() * 0.09 * RSCALE + 20
		local pitch2 = pitch1 - 255
		local pitch3 = pitch2 - 255

		self.Engine1Sound:PlayEx(0.98, math.min(255, pitch1))

		if 0 < pitch2 then
			self.Engine2Sound:PlayEx(0.98, math.min(255, pitch2))
		else
			self.Engine2Sound:Stop()
		end

		if 0 < pitch3 then
			self.Engine3Sound:PlayEx(0.98, math.min(255, pitch3))
		else
			self.Engine3Sound:Stop()
		end
	end

	local vPos = self:GetPos()
	self.Emitter:SetPos(vPos)

	if self.NextTrail <= RealTime() then
		self.NextTrail = self.NextTrail + 0.02

		local right = self:GetRight()
		local fwd = self:GetForward()

		table.insert(self.RightTrails, 1, vPos + fwd * self.Back + right * self.RightLight)
		table.insert(self.LeftTrails, 1, vPos + fwd * self.Back + right * self.LeftLight)
		table.insert(self.TrailSpeeds, 1, self:GetVelocity():Length() * 0.05 * RSCALE)

		if 48 == #self.RightTrails then
			table.remove(self.RightTrails, 48)
			table.remove(self.LeftTrails, 48)
			table.remove(self.TrailSpeeds, 48)
		end
	end

	-- Should be in GM:Think
	--[[if MySelf:GetHoverGear() == self and self:GetVelocity():Length() >= SOUNDBARRIER and not self.TriedSoundBarrier then
		self.TriedSoundBarrier = true
		RunConsoleCommand("_getaward", "sonic_boom")
	end]]
end

function ENT:OnRemove()
	self.Engine1Sound:Stop()
	self.Engine2Sound:Stop()
	self.Engine3Sound:Stop()
	self.AlarmSound:Stop()
	self.Emitter:Finish()
end
